import axios from "axios";
import type { HttpRequestConfig } from "./type.d";
import type { Canceler } from "axios";
import { isFunction } from "lodash-unified";

// 储存 pending 中的函数
let pendingAjaxMap = new Map<string, Canceler>();

// 生成重复标识
export const getDuplicatedKey = (config: HttpRequestConfig) =>
  [config.method, config.url].join("&");

export class AxiosCanceler {
  /**
   * 添加请求到 pending map
   * @param config
   */
  addPending(config: HttpRequestConfig) {
    this.removePending(config);
    const url = getDuplicatedKey(config);
    config.cancelToken =
      config.cancelToken ||
      new axios.CancelToken((cancel) => {
        if (!pendingAjaxMap.has(url)) {
          // 如果 pending map里不存在该请求，则缓存该请求
          pendingAjaxMap.set(url, cancel);
        }
      });
  }

  removePending(config: HttpRequestConfig) {
    const url = getDuplicatedKey(config);

    if (pendingAjaxMap.has(url)) {
      // 如果当前 map 中存在该请求，执行该请求的取消函数取消该请求，并从 pending map 中移除
      const cancel = pendingAjaxMap.get(url);
      cancel && cancel(url);
      pendingAjaxMap.delete(url);
    }
  }

  /**
   * 取消所有请求，并清空 pending map
   */
  removeAllPending() {
    pendingAjaxMap.forEach((cancel) => {
      cancel && isFunction(cancel) && cancel();
    });
    pendingAjaxMap.clear();
  }

  /**
   * 初始化 pending map
   */
  reset(): void {
    pendingAjaxMap = new Map<string, Canceler>();
  }
}
